package cn.com.jenson.service.carport.service.impl;

import cn.com.jenson.common.ImportVerifierVo;
import cn.com.jenson.common.SelectVo;
import cn.com.jenson.dao.carport.bo.CarportBo;
import cn.com.jenson.dao.carport.searchBo.CarportSearchBo;
import cn.com.jenson.dao.carport.vo.CarportVo;
import cn.com.jenson.entity.carport.Carport;
import cn.com.jenson.entity.carport.QCarport;
import cn.com.jenson.exception.BusinessException;
import cn.com.jenson.service.carport.repository.CarportRepository;
import cn.com.jenson.service.carport.service.CarportService;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CarportServiceImpl implements CarportService {

    @Resource
    private CarportRepository carportRepository;

    @Resource
    private JPAQueryFactory jpaQueryFactory;

    QCarport qCarport = QCarport.carport;

    @Override
    public Page<CarportVo> pageAll(CarportSearchBo carportSearchBo) {
        JPAQuery<Carport> jpaQuery = jpaQueryFactory
                .selectFrom(qCarport)
                .where(getWhere(carportSearchBo));

        List<Carport> list = jpaQuery
                .offset(carportSearchBo.getPageRequest().getOffset())
                .limit(carportSearchBo.getPageRequest().getPageSize())
                .fetch();

        Page<CarportVo> page = new PageImpl<>(
                new CarportVo().fromEntities(list, CarportVo.class),
                carportSearchBo.getPageRequest(),
                jpaQuery.fetchCount()
        );

        supplement(page);
        return page;
    }

    @Override
    public List<CarportVo> listAll(CarportSearchBo carportSearchBo) {
        List<CarportVo> list = new CarportVo()
                .fromEntities(
                        jpaQueryFactory
                                .selectFrom(qCarport)
                                .where(getWhere(carportSearchBo))
                                .fetch(),
                        CarportVo.class
                );
        supplement(list);
        return list;
    }

    @Override
    public CarportVo get(CarportSearchBo carportSearchBo) throws InstantiationException, IllegalAccessException {
        CarportVo carportVo = new CarportVo().fromEntity(
                carportRepository.findByIdAndDeleted(carportSearchBo.getId(), false)
                        .orElseThrow(() -> new BusinessException("找不到id为" + carportSearchBo.getId() + "的车位")),
                CarportVo.class
        );

        supplement(carportVo);

        return carportVo;
    }

    @Override
    public BooleanExpression getWhere(CarportSearchBo carportSearchBo) {
        return qCarport.deleted.eq(false);
    }

    @Override
    public CarportVo edit(CarportBo carportBo) throws InstantiationException, IllegalAccessException {
        Carport carport = new CarportBo().toEntity(carportBo, Carport.class);
        carport = carportRepository.save(carport);
        return new CarportVo().fromEntity(carport, CarportVo.class);
    }

    @Override
    public List<CarportVo> editAll(List<CarportBo> carportBos) {
        List<Carport> carportList = new CarportBo().toEntities(carportBos, Carport.class);
        carportList = carportRepository.saveAll(carportList);
        return new CarportVo().fromEntities(carportList, CarportVo.class);
    }

    @Override
    public CarportVo deleted(CarportSearchBo carportSearchBo) throws InstantiationException, IllegalAccessException {
        Carport carport = carportRepository.findByIdAndDeleted(carportSearchBo.getId(), false)
                .orElseThrow(() -> new BusinessException("找不到id为" + carportSearchBo.getId() + "的车位"));
        carport.setDeleted(true);
        carport = carportRepository.save(carport);
        return new CarportVo().fromEntity(carport, CarportVo.class);
    }

    @Override
    public List<CarportVo> deletedAll(List<CarportSearchBo> carportSearchBos) {
        List<Integer> idList = carportSearchBos.stream().map(CarportSearchBo::getId).collect(Collectors.toList());
        List<Carport> carportList = carportRepository.findByIdInAndDeleted(idList,false);
        carportList = carportList.stream().peek(item -> item.setDeleted(true)).collect(Collectors.toList());
        carportList = carportRepository.saveAll(carportList);
        return new CarportVo().fromEntities(carportList, CarportVo.class);
    }

    @Override
    public List<ImportVerifierVo> importTemplateVerifiers() {
        return null;
    }

    @Override
    public void importTemplateDownload(HttpServletResponse response) throws IOException {

    }

    @Override
    public List<SelectVo<String, Integer, CarportVo>> option() {
        return null;
    }

    @Override
    public void supplement(CarportVo carportVo) {

    }

    @Override
    public void supplement(List<CarportVo> carportVos) {

    }

    @Override
    public void supplement(Page<CarportVo> carportVos) {

    }

    @Override
    public CarportVo simulate(CarportBo carportBo) {
        return null;
    }
}
